package minesweeper;

/**
 * 表示雷区中的一个单元格。单元格有两个可以修改的正交属性：
 * 单元格可以是埋有地雷的或没有地雷的，单元格可以是隐藏的、标记的（表示隐藏了一个地雷）或已揭露的。
 */
public class Cell
{
	/**
	 * 表示用户如何与单元格交互。
	 */
	private enum CellInteractionStatus
	{
		/**
		 * 单元格是隐藏的且未被标记。
		 */
		HIDDEN,

		/**
		 * 单元格是隐藏的但已被玩家标记为隐藏了一个地雷。
		 */
		MARKED,

		/**
		 * 单元格已被揭露。
		 */
		REVEALED
	}

	private boolean aIsMined; // 默认值为 false
	private CellInteractionStatus aInteractionStatus = CellInteractionStatus.HIDDEN;

	public Cell() {}

	/**
	 * @return 如果单元格是隐藏的（无论是否被标记），返回 true。
	 */
	public boolean isHidden()
	{
		return aInteractionStatus != CellInteractionStatus.REVEALED;
	}

	/**
	 * @return 如果单元格被标记，返回 true。
	 */
	public boolean isMarked()
	{
		return aInteractionStatus == CellInteractionStatus.MARKED;
	}

	/**
	 * @return 如果单元格有地雷，返回 true；否则返回 false。
	 */
	public boolean isMined()
	{
		return aIsMined;
	}

	/**
	 * 更改此单元格的状态以表示已揭露的单元格。
	 */
	public void reveal()
	{
		aInteractionStatus = CellInteractionStatus.REVEALED;
	}

	/**
	 * 如果此单元格未被标记，则标记它。如果单元格已被标记，
	 * 则取消标记。
	 *
	 * @pre isHidden() == true;
	 */
	public void toggleMark()
	{
		assert isHidden();
		if(aInteractionStatus == CellInteractionStatus.MARKED)
		{
			aInteractionStatus = CellInteractionStatus.HIDDEN;
		}
		else
		{
			aInteractionStatus = CellInteractionStatus.MARKED;
		}
	}

	/**
	 * 将单元格标记为有地雷。
	 */
	public void mine()
	{
		aIsMined = true;
	}
}